<template>
  <div class="home-page" @subscribe="$emit('subscribe')">
    <div class="main-content">
      <!-- 左侧文章列表 -->
      <div class="article-section">
        <!-- 公告 -->
        <SiteAnnouncement
          v-if="announcements.length"
          :announcements="announcements"
          @open-modal="appStore.toggleAnnouncementModal"
        />
        <!-- 特别推荐 -->
        <FeaturedArticles :articles="featuredArticles" />
        <!-- 分类选项卡 -->
        <div ref="categoryTabsRef" class="tabs-scroll-target">
          <CategoryTabs
            :categories="categories"
            :active-category-id="activeCategoryId"
            @change="appStore.setActiveCategoryId"
          />
        </div>
        <!-- 文章列表 -->
        <ArticleList :articles="paginatedArticles" :loading="loading" />
        <!-- 分页 -->
        <Pagination
          :total="total"
          :current-page="currentPage"
          :page-size="pageSize"
          @page-change="handlePageChange"
        />
      </div>
      <!-- 右侧边栏 -->
      <aside class="sidebar">
        <div class="sidebar-inner">
          <InfoCard @subscribe="$emit('subscribe')" />
          <RankingCard :articles="articles" />
        </div>
      </aside>
    </div>

    <!-- 公告模态框 -->
    <AnnouncementModal
      :show="appStore.announcementModalVisible"
      :announcements="announcements"
      @close="appStore.toggleAnnouncementModal"
    />

    <!-- 订阅弹窗 Teleport 到 body，z-index 提升 -->
    <Teleport to="body">
      <transition name="fade">
        <div v-if="showSubModal" class="sub-modal-mask" @click.self="showSubModal = false">
          <div class="sub-modal minimal">
            <button class="close-btn minimal" @click="showSubModal = false">
              <i class="ri-close-line"></i>
            </button>
            <div class="icon-row">
              <span class="icon">📬</span>
            </div>
            <div class="title">订阅本博客</div>
            <div class="desc">文章更新邮件通知（可随时退订）</div>
            <form class="form-row" @submit.prevent="handleSubscribe">
              <input
                v-model="subEmail"
                type="email"
                placeholder="输入邮箱地址"
                required
                class="input"
              />
              <button class="btn" type="submit">订阅</button>
            </form>
          </div>
        </div>
      </transition>
    </Teleport>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, nextTick, watch, onUnmounted } from 'vue'
import { useAppStore } from '@/stores/app'
import { storeToRefs } from 'pinia'

import FeaturedArticles from './components/FeaturedArticles.vue'
import SiteAnnouncement from './components/SiteAnnouncement.vue'
import CategoryTabs from './components/CategoryTabs.vue'
import ArticleList from './components/ArticleList.vue'
import InfoCard from './components/sidebar/InfoCard.vue'
import RankingCard from './components/sidebar/RankingCard.vue'
import AnnouncementModal from './components/AnnouncementModal.vue'
import Pagination from '@/components/Pagination.vue'
import { getRecommendArticles, getArticlePage } from '@/api/article'
import { getNoticeList } from '@/api/home'
import { timeAgo } from '@/utils/timeUtils'

const appStore = useAppStore()
const { categories, activeCategoryId } = storeToRefs(appStore)

const categoryTabsRef = ref(null)

// --- 公告数据（后端） ---
const announcements = ref([])
const articles = ref([])
const total = ref(0)

// --- 状态管理 ---
const loading = ref(false)
const currentPage = ref(1)
const pageSize = ref(8)

const featuredArticles = ref([])

const paginatedArticles = computed(() => articles.value)

// --- 方法 ---
function normalizeHtmlContent(content) {
  if (typeof content !== 'string') return content
  const trimmed = content.trim()
  if (trimmed.startsWith("'") && trimmed.endsWith("'")) {
    return trimmed.slice(1, -1)
  }
  return content
}
function getScrollContainer() {
  const main = document.querySelector('.layout-main')
  if (main && main.scrollHeight > main.clientHeight + 10) {
    return main
  }
  return window
}

const scrollToCategoryTabs = () => {
  nextTick(() => {
    setTimeout(() => {
      const el = categoryTabsRef.value
      if (!el) return

      const scrollContainer = getScrollContainer()
      const rect = el.getBoundingClientRect()
      const header = document.querySelector('.header')
      const headerHeight = header ? header.offsetHeight : 60

      if (scrollContainer === window) {
        const top = window.scrollY + rect.top - headerHeight
        try {
          window.scrollTo({ top, behavior: 'smooth' })
        } catch {
          window.scrollTo(0, top)
        }
      } else {
        const containerRect = scrollContainer.getBoundingClientRect()
        const scrollTop = scrollContainer.scrollTop + (rect.top - containerRect.top) - headerHeight
        try {
          scrollContainer.scrollTo({ top: scrollTop, behavior: 'smooth' })
        } catch {
          scrollContainer.scrollTop = scrollTop
        }
      }
    }, 80)
  })
}

const handlePageChange = (page) => {
  currentPage.value = page
  loadArticles()
  scrollToCategoryTabs()
}

// --- 滚动监听以控制FAB按钮 ---
let observer = null
function setupFabObserver() {
  if (observer && categoryTabsRef.value) {
    observer.unobserve(categoryTabsRef.value)
  }
  const header = document.querySelector('.header')
  const headerHeight = header ? header.offsetHeight : 60
  const scrollContainer = getScrollContainer()
  const observerOptions = {
    root: scrollContainer === window ? null : scrollContainer,
    rootMargin: `-${headerHeight}px 0px 0px 0px`,
    threshold: 1.0,
  }
  observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      appStore.setCategoryFabVisible(!entry.isIntersecting)
    })
  }, observerOptions)
  if (categoryTabsRef.value) {
    observer.observe(categoryTabsRef.value)
  }
}

onMounted(() => {
  appStore.setCategoryFabVisible(false)
  setupFabObserver()
})

onUnmounted(() => {
  if (observer && categoryTabsRef.value) {
    observer.unobserve(categoryTabsRef.value)
  }
  appStore.setCategoryFabVisible(false)
})

// --- Watchers ---
watch(activeCategoryId, (newVal, oldVal) => {
  if (newVal !== oldVal) {
    currentPage.value = 1 // Reset to first page on category change
    loadArticles()
    scrollToCategoryTabs()
  }
})

// --- Lifecycle ---
onMounted(() => {
  loading.value = true
  // 获取后端推荐文章列表
  getRecommendArticles()
    .then((list) => {
      featuredArticles.value = list
    })
    .finally(() => {
      loading.value = false
    })
  // 拉取分类列表
  appStore.fetchCategories()
  // 拉取文章分页
  loadArticles()
  // 拉取公告列表
  loadNotices()
})

// --- 联调文章分页 ---
async function loadArticles() {
  try {
    loading.value = true
    const categoryId = activeCategoryId.value === null ? 'all' : activeCategoryId.value
    const res = await getArticlePage(categoryId, currentPage.value, pageSize.value)
    const list = res?.records || res?.list || []
    articles.value = list.map((a) => ({
      id: a.id,
      title: a.title,
      description: a.description,
      author: a.author?.nickname,
      views: a.viewsNum,
      likes: a.likeNum,
      comments: a.commentsNum,
      category: a.category?.name,
      cover: a.picUrl,
      coverType: !a.picUrl ? 'none' : a.coverStyle === '1' ? 'small' : 'large',
      date: a.createOn,
    }))
    total.value = res?.total ?? res?.count ?? list.length
  } catch {
    articles.value = []
    total.value = 0
  } finally {
    loading.value = false
  }
}

// --- 公告联调 ---
async function loadNotices() {
  try {
    const res = await getNoticeList()
    const list = res || []
    // SiteAnnouncement 依赖字段：id, title, content
    announcements.value = list.map((n) => ({
      id: n.id,
      title: n.title,
      content: normalizeHtmlContent(n.content),
      date: n.createOn,
      author: n.createUserName,
      timeAgo: timeAgo(n.createOn),
    }))
  } catch (e) {
    announcements.value = []
  }
}
</script>

<style lang="scss" scoped>
@import '@/assets/styles/_mixins.scss';

.tabs-scroll-target {
  /* Adjust this value to match your sticky header's height + desired margin */
  scroll-margin-top: 80px;
}

.home-page {
  padding: 24px 0;
}

.main-content {
  display: flex;
  gap: 24px;
  margin-top: 24px;
}

.article-section {
  flex: 1;
  min-width: 0;
}

.sidebar {
  width: 300px;
  flex-shrink: 0;
}

.sidebar-inner {
  position: sticky;
  top: 84px; /* 60px (header) + 24px (gap) */
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

// 响应式布局
@include respond-to('lg') {
  .sidebar {
    display: none;
  }

  .home-page {
    padding: 10px 0;
  }

  .main-content {
    display: flex;
    gap: 24px;
    margin-top: 12px;
  }
}

.sub-modal-mask {
  position: fixed;
  inset: 0;
  z-index: 4000;
  background: rgba(30, 34, 45, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
}
.sub-modal.minimal {
  background: #fff;
  border-radius: 20px;
  box-shadow: 0 4px 32px rgba(0, 0, 0, 0.1);
  width: 340px;
  max-width: 92vw;
  padding: 2em 1.5em 1.5em 1.5em;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  animation: popIn 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 4100;
}
</style>
